// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************
#ifndef __H_MK_SKELETON_DATA_LOADER__
#define __H_MK_SKELETON_DATA_LOADER__

#include "mk_skeleton.h"
#include "mk_error.h"

namespace MK3DE
{
	class MK3DE_API CSkeletonDataLoader
	{
	public:
		struct BoneData
		{
			//! Bone's name
			std::string name;

			//! The index of the parent bone.
			int parentIdx;

			/** If there is no animation for a transformation, then the frame count is 1 or 
			the frame count is the same as skeleton frame count. */
			std::vector<D3DXVECTOR3> vecAniTranslation;
			std::vector<D3DXQUATERNION> vecAniRotation;
			std::vector<D3DXVECTOR3> vecAniScale;
			std::vector<D3DXQUATERNION> vecAniScaleRotation;
		};

		struct SkeletonData
		{
			~SkeletonData()
			{
				for (std::vector<BoneData*>::iterator it = vecBoneData.begin(); it != vecBoneData.end(); ++it)
				{
					BoneData* boneData = *it;
					SAFE_DELETE(boneData);
				}
			}

			//! All bones' animation data.
			std::vector<BoneData*> vecBoneData;

			//! The name of the skeleton animation.
			std::string name;

			//! Frame count of the skeleton animation.
			WORD frameCount;

			//! Whether it is relative transformation.
			BOOL relative;
		};

	public:
		static BOOL LoadSkeletonData(const BYTE* buffer, DWORD size, SkeletonData& data);
		static BOOL SaveToFile(const char* fileName, CSkeletonDataLoader::SkeletonData& skeletonData);

	private:
		static BOOL __LoadBoneData(BoneData* pBoneData, TiXmlElement* pBoneNode);

		static BOOL __LoadTransformation(BoneData* pBoneData, TiXmlElement* transformationNode);

		static BOOL __LoadTranslationAnimation(BoneData* pBoneData, TiXmlElement* translationNode);
		static BOOL __LoadRotationAnimation(BoneData* pBoneData, TiXmlElement* rotationNode);
		static BOOL __LoadScaleAnimation(BoneData* pBoneData, TiXmlElement* scaleNode);
		static BOOL __LoadScaleRotationAnimation(BoneData* pBoneData, TiXmlElement* scaleRotationNode);
	};
}

#endif // __H_MK_SKELETON_DATA_LOADER__